/** header **/

#include "my_thread_list.h"

/** generic list data structure **/
struct __generic_list {
  struct __generic_list * next;
  generic content;
};

/**********************************************************************************************
 * __generic_list_empty
 *********************************************************************************************/
generic_list __generic_list_empty () {
  return NULL;
}

/**********************************************************************************************
 * __generic_list_new
 *********************************************************************************************/
generic_list __generic_list_new (generic _generic) {
  generic_list list = (generic_list) malloc (sizeof (struct __generic_list));
  
  if (list == NULL)
    __internal_error (ERROR_MEMORY_ALLOCATION, __FILE__, __func__,__LINE__);
  
  list->next = NULL;
  list->content = _generic;
  return list;
}

/**********************************************************************************************
 * __generic_list_delete
 *********************************************************************************************/
void __generic_list_delete (generic_list list) {
  if (list != NULL) {
    __generic_list_delete (list->next);
    list->next = NULL;
    free (list);
  }
  return ;
}

/**********************************************************************************************
 * __generic_list_append
 *********************************************************************************************/
generic_list __generic_list_append (generic first, generic second) {
  generic_list first_list = __generic_list_new (first);
  generic_list second_list = __generic_list_new (second);  
  
  if (first_list == NULL || second_list == NULL)
    __internal_error (ERROR_NULL_POINTER, __FILE__, __func__,__LINE__);
  
  first_list->next = second_list;
  
  return first_list;
}

/**********************************************************************************************
 * __generic_list_insert
 *********************************************************************************************/
generic_list __generic_list_insert (generic_list first, generic _generic) {
  generic_list second = __generic_list_new (_generic);

  if (second == NULL)
    __internal_error (ERROR_NULL_POINTER, __FILE__, __func__,__LINE__);
  
  if (first == NULL) {
    second->content = _generic;
    return second;

  } else if (first->next != NULL) {
    __generic_list_insert (first->next, _generic);

  } else {
    first->next = second;
  }
  return first;
}
/**********************************************************************************************
 * __generic_list_remove
 *********************************************************************************************/
generic_list __generic_list_remove (generic_list first, generic _generic){
	generic_list_iterator prev=__generic_list_iterator(first);
	generic_list_iterator curr=__generic_list_iterator(first);
	while(!__generic_list_iterator_end(curr)){
		if(_generic_list_iterator_current(curr)==_generic){
			prev->next=__generic_list_iterator_next(curr);
			return first;
		}
		prev=curr;
		curr=__generic_list_iterator_next(curr);

	}
	return first;
}
/**********************************************************************************************
 * __generic_list_concatenate
 *********************************************************************************************/
generic_list __generic_list_concatenate (generic_list first, generic_list second) {
  if (first == NULL) return second;

  generic_list current = first;
  while (current->next != NULL) current = current->next;
  
  current->next = second;
  return first;
}

/**********************************************************************************************
 * __generic_list_iterator_new
 *********************************************************************************************/
generic_list_iterator __generic_list_iterator (generic_list list) {
  return (generic_list_iterator) list;
}

/**********************************************************************************************
 * __generic_list_iterator_current
 *********************************************************************************************/
generic __generic_list_iterator_current (generic_list_iterator iterator) {
  if (iterator == NULL)
    __internal_error (ERROR_NULL_POINTER, __FILE__, __func__,__LINE__);
  return iterator->content;
}

/**********************************************************************************************
 * __generic_list_iterator_next
 *********************************************************************************************/
generic_list_iterator __generic_list_iterator_next (generic_list_iterator iterator) {
  if (iterator == NULL)
    __internal_error (ERROR_NULL_POINTER, __FILE__, __func__,__LINE__);

  return (generic_list_iterator) iterator->next;
}

/**********************************************************************************************
 * __generic_list_iterator_end
 *********************************************************************************************/
__boolean __generic_list_iterator_end (generic_list_iterator iterator) {
  return (iterator == NULL);
}
